package com.zyq.interceptor;

import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.executor.statement.StatementHandler;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.plugin.*;
import java.lang.reflect.Field;
import java.sql.Connection;
import java.time.LocalDateTime;
import java.util.Properties;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 此拦截器会在MyBatis为接口生成的代理对象执行之前执行
 * <p>基于MyBatis的自动插入“创建时间”、更新"最后修改时间"的拦截器</p>
 *
 * <p>需要SQL语法预编译之前进行拦截，则拦截类型为StatementHandler，拦截方法是prepare</p>
 * type = StatementHandler.class,表示拦截StatementHandler类型的代理对象的prepare方法，此方法的参数需要是Connection和Integer
 *
 * <p>具体的拦截处理由内部的intercept()方法实现</p>
 *
 * <p>注意：由于仅适用于当前项目，并不具备范用性，所以：</p>
 *
 * <ul>
 * <li>拦截所有的update方法（根据SQL语句以update前缀进行判定），无法不拦截某些update方法</li>
 * <li>所有数据表中"最后修改时间"的字段名必须一致，由本拦截器的FIELD_MODIFIED属性进行设置</li>
 * </ul>
 */
@Slf4j
@Intercepts({@Signature(
        type = StatementHandler.class,
        method = "prepare",
        args = {Connection.class, Integer.class}
)})
public class InsertUpdateTimeInterceptor implements Interceptor {
    /**
     * 自动添加的创建时间字段
     */
    private static final String FIELD_CREATE = "gmt_create";
    /**
     * 自动更新时间的字段
     */
    private static final String FIELD_MODIFIED = "gmt_modified";
    /**
     * SQL语句类型：其它（暂无实际用途）
     */
    private static final int SQL_TYPE_OTHER = 0;
    /**
     * SQL语句类型：INSERT
     */
    private static final int SQL_TYPE_INSERT = 1;
    /**
     * SQL语句类型：UPDATE
     */
    private static final int SQL_TYPE_UPDATE = 2;
    /**
     * 查找SQL类型的正则表达式：INSERT
     */
    private static final String SQL_TYPE_PATTERN_INSERT = "^insert\\s";
    /**
     * 查找SQL类型的正则表达式：UPDATE
     */
    private static final String SQL_TYPE_PATTERN_UPDATE = "^update\\s";
    /**
     * 查询SQL语句片段的正则表达式：gmt_modified片段
     */
    private static final String SQL_STATEMENT_PATTERN_MODIFIED = ",\\s*" + FIELD_MODIFIED + "\\s*=";
    /**
     * 查询SQL语句片段的正则表达式：gmt_create片段
     */
    private static final String SQL_STATEMENT_PATTERN_CREATE = ",\\s*" + FIELD_CREATE + "\\s*[,)]?";
    /**
     * 查询SQL语句片段的正则表达式：WHERE子句
     */
    private static final String SQL_STATEMENT_PATTERN_WHERE = "\\s+where\\s+";
    /**
     * 查询SQL语句片段的正则表达式：VALUES子句
     */
    private static final String SQL_STATEMENT_PATTERN_VALUES = "\\)\\s*values?\\s*\\(";

    public Object intercept(Invocation invocation) throws Throwable {
        // 日志
        log.debug("准备拦截SQL语句……");
        // 获取boundSql，即：封装了即将执行的SQL语句及相关数据的对象
        BoundSql boundSql = getBoundSql(invocation);
        // 从boundSql中获取SQL语句
        String sql = getSql(boundSql);
        // 日志
        log.debug("原SQL语句：{}", sql);
        // 准备新SQL语句
        String newSql = null;
        // 判断原SQL类型
        switch (getOriginalSqlType(sql)) {
            case SQL_TYPE_INSERT:
                // 日志
                log.debug("原SQL语句是【INSERT】语句，准备补充更新时间……");
                // 准备新SQL语句
                newSql = appendCreateTimeField(sql, LocalDateTime.now());
                break;
            case SQL_TYPE_UPDATE:
                // 日志
                log.debug("原SQL语句是【UPDATE】语句，准备补充更新时间……");
                // 准备新SQL语句
                newSql = appendModifiedTimeField(sql, LocalDateTime.now());
                break;
        }
        // 应用新SQL
        if (newSql != null) {
            // 日志
            log.debug("新SQL语句：{}", newSql);
            reflectAttributeValue(boundSql, "sql", newSql);
        }

        // 执行调用，即拦截器放行，执行后续部分
        return invocation.proceed();
    }

    public String appendModifiedTimeField(String sqlStatement, LocalDateTime dateTime) {
        //此Pattern包含gmt_modified字段名的正则
        Pattern gmtPattern = Pattern.compile(SQL_STATEMENT_PATTERN_MODIFIED, Pattern.CASE_INSENSITIVE);
        //如果sqlStatement的sql语句中包含gmt_modified字段名。就不再执行本方法中拼接gmt_modified字段信息的代码
        if (gmtPattern.matcher(sqlStatement).find()) {
            log.debug("原SQL语句中已经包含gmt_modified，将不补充添加时间字段");
            return null;
        }
        StringBuilder sql = new StringBuilder(sqlStatement);
        //此Pattern正则中包含了where关键字
        Pattern whereClausePattern = Pattern.compile(SQL_STATEMENT_PATTERN_WHERE, Pattern.CASE_INSENSITIVE);
        //Matcher匹配器表示用于将上边的正则和sql进行匹配
        Matcher whereClauseMatcher = whereClausePattern.matcher(sql);
        // 查找 where 子句的位置
        // 注意find()方法只会执行一次，如果前边已经执行过一次whereClauseMatcher.find()，则这个if条件是不会成立的
        if (whereClauseMatcher.find()) {
            int start = whereClauseMatcher.start();
            int end = whereClauseMatcher.end();
            String clause = whereClauseMatcher.group();
            log.debug("在原SQL语句的 {}位置 到 {}位置 找到 {}", start, end, clause);
            String newSetClause = ", " + FIELD_MODIFIED + "='" + dateTime + "'";
            sql.insert(start, newSetClause);
            log.debug("在原SQL语句: {}中 插入sql片段 {}", start, newSetClause);
            log.debug("最终生成的SQL语句为: {}", sql);
            return sql.toString();
        }
        return null;
    }

    public String appendCreateTimeField(String sqlStatement, LocalDateTime dateTime) {
        // 如果 SQL 中已经包含 gmt_create 就不在添加这两个字段了
        //Pattern是包含两个字段名的一段sql片段
        Pattern gmtPattern = Pattern.compile(SQL_STATEMENT_PATTERN_CREATE, Pattern.CASE_INSENSITIVE);
        // 注意find()方法只会执行一次，如果前边已经执行过一次gmtPattern.matcher(sqlStatement).find()，则这个if条件是不会成立的
        if (gmtPattern.matcher(sqlStatement).find()) {
            log.debug("已经包含 gmt_create 不再添加 时间字段");
            return null;
        }
        // INSERT into table (xx, xx, xx ) values (?,?,?)中 查找 ) values ( 的位置
        StringBuilder sql = new StringBuilder(sqlStatement);
        //此Pattern是包含  ")values("  的正则对象
        Pattern valuesClausePattern = Pattern.compile(SQL_STATEMENT_PATTERN_VALUES, Pattern.CASE_INSENSITIVE);
        Matcher valuesClauseMatcher = valuesClausePattern.matcher(sql);
        // 查找 ") values " 的位置
        if (valuesClauseMatcher.find()) {
            int start = valuesClauseMatcher.start();
            int end = valuesClauseMatcher.end();
            String str = valuesClauseMatcher.group();
            //举例如下：
            //"insert into ams_admin_role (admin_id,role_id)values(1,1)"
            //找到字符串：)values(的位置是：44,52
            //提示： 从0开始数 )values( 左括号的位置是44    第一个1的位置是52
            log.debug("InsertUpdateTimeInterceptor::appendCreateTimeField():::找到字符串：{}的位置是：{},{}", str, start, end);
            // 插入字段列表
            String fieldNames = ", " + FIELD_CREATE + ", " + FIELD_MODIFIED;
            sql.insert(start, fieldNames);
            //"insert into ams_admin_role (admin_id,role_id)values(1,1)",
            //44位置处插入字段列表,gmt_create,gmt_modified
            log.debug("InsertUpdateTimeInterceptor::appendCreateTimeField()::: {}位置处插入字段列表{}", start,fieldNames);
            // 定义查找参数值位置的 正则表达 “)”
            Pattern paramPositionPattern = Pattern.compile("\\)");
            Matcher paramPositionMatcher = paramPositionPattern.matcher(sql);
            // 从 ) values ( 的后面位置 end 开始查找 结束括号的位置
            String param = ", '" + dateTime + "', '" + dateTime + "'";//拼接出两个时间数据的sql片段
            int position = end + fieldNames.length();//从sql中匹配到  ")values(" 的位置加上  ",gmt_create,gmt_update"的长度
            //end 52 + fieldNames.length()  24=76
            log.debug("InsertUpdateTimeInterceptor::appendCreateTimeField()::: end{} + fieldNames.length(){}={}", end,fieldNames.length(),position);
            while (paramPositionMatcher.find(position)) {
                start = paramPositionMatcher.start();
                end = paramPositionMatcher.end();
                str = paramPositionMatcher.group();
                //insert into ams_admin_role (admin_id,role_id,gmt_create,gmt_modified)values(1,1)
                //找到参数值插入位置),79,80 //从最后一个 ) 符号位置处(下标位置为79的位置)开始插入
                log.debug("sql '{}' 找到参数值插入位置{},{},{}", sql,str, start, end);
                sql.insert(start, param);
                //在79处插入参数值, '2022-12-25T21:38:42.410','2022-12-25T21:38:42.410'
                log.debug("在 {} 插入参数值 {}", start, param);
                position = end + param.length();
            }
            if (position == end) {
                log.warn("没有找到插入数据的位置！");
                return null;
            }
        } else {
            log.warn("没有找到 ) values (");
            return null;
        }
        //insert into ams_admin_role (admin_id,role_id,gmt_create,gmt_modified)values(1,1, '2022-12-25T22:27:39.070','2022-12-25T22:27:39.070')
        log.debug("生成SQL：{}", sql);
        return sql.toString();
    }


    @Override
    public Object plugin(Object target) {
        // 本方法的代码是相对固定的
        if (target instanceof StatementHandler) {
            //this就表示当前类对象(当前的拦截器)
            return Plugin.wrap(target, this);
        } else {
            return target;
        }
    }

    @Override
    public void setProperties(Properties properties) {
        // 无须执行操作
    }

    /**
     * <p>获取BoundSql对象，此部分代码相对固定</p>
     *
     * <p>注意：根据拦截类型不同，获取BoundSql的步骤并不相同，此处并未穷举所有方式！</p>
     *
     * @param invocation 调用对象
     * @return 绑定SQL的对象
     */
    private BoundSql getBoundSql(Invocation invocation) {
        Object invocationTarget = invocation.getTarget();
        if (invocationTarget instanceof StatementHandler) {
            StatementHandler statementHandler = (StatementHandler) invocationTarget;
            return statementHandler.getBoundSql();
        } else {
            throw new RuntimeException("获取StatementHandler失败！请检查拦截器配置！");
        }
    }

    /**
     * 从BoundSql对象中获取SQL语句
     *
     * @param boundSql BoundSql对象
     * @return 将BoundSql对象中封装的SQL语句进行转换小写、去除多余空白后的SQL语句
     */
    private String getSql(BoundSql boundSql) {
        return boundSql.getSql().toLowerCase().replaceAll("\\s+", " ").trim();
    }

    /**
     * <p>通过反射，设置某个对象的某个属性的值</p>
     *
     * @param object         需要设置值的对象
     * @param attributeName  需要设置值的属性名称
     * @param attributeValue 新的值
     * @throws NoSuchFieldException   无此字段异常
     * @throws IllegalAccessException 非法访问异常
     */
    private void reflectAttributeValue(Object object, String attributeName, String attributeValue) throws NoSuchFieldException, IllegalAccessException {
        Field field = object.getClass().getDeclaredField(attributeName);
        field.setAccessible(true);
        field.set(object, attributeValue);
    }

    /**
     * 获取原SQL语句类型
     *
     * @param sql 原SQL语句
     * @return SQL语句类型
     */
    private int getOriginalSqlType(String sql) {
        Pattern pattern;
        pattern = Pattern.compile(SQL_TYPE_PATTERN_INSERT, Pattern.CASE_INSENSITIVE);
        if (pattern.matcher(sql).find()) {
            return SQL_TYPE_INSERT;
        }
        pattern = Pattern.compile(SQL_TYPE_PATTERN_UPDATE, Pattern.CASE_INSENSITIVE);
        if (pattern.matcher(sql).find()) {
            return SQL_TYPE_UPDATE;
        }
        return SQL_TYPE_OTHER;
    }

}





//package com.zyq.interceptor;
//
//
//import lombok.extern.slf4j.Slf4j;
//import org.apache.ibatis.executor.statement.StatementHandler;
//import org.apache.ibatis.mapping.BoundSql;
//import org.apache.ibatis.plugin.*;
//
//import java.lang.reflect.Field;
//import java.sql.Connection;
//import java.time.LocalDateTime;
//import java.util.Properties;
//import java.util.regex.Matcher;
//import java.util.regex.Pattern;
//
///**
// * <p>基于MyBatis实现的拦截器，用于在插入数据时自动插入“创建时间”、或在修改数据时更新"最后修改时间"的拦截器</p>
// * <p>需要SQL语法预编译之前进行拦截，则拦截类型为StatementHandler，拦截方法是prepare</p>
// */
//@Slf4j
//@Intercepts({@Signature(type= StatementHandler.class, method = "prepare",args={Connection.class,Integer.class})})
//public class InsertUpdateTimeInterceptor implements Interceptor {
//
//    /**自动更新时间的字段名*/
//    private static  final  String FIELD_CREATE="gmt_create";    /**自动更新时间的字段名*/
//
//    /**自动更新时间的字段名*/
//    private static  final  String FIELD_MODIFIED="gmt_modified";    /**自动更新时间的字段名*/
//
//    /**SQL语句类型，其他(暂无实际用途)*/
//    private static  final int SQL_TYPE_OTHER=0;
//
//    /**SQL语句类型：insert*/
//    private static  final int SQL_TYPE_INSERT=1;
//
//    /**SQL语句类型：update*/
//    private static  final int SQL_TYPE_UPDATE=2;
//
//    /**查找SQL类型的正则表达式： INSERT*/
//    private static final String SQL_TYPE_PATTERN_INSERT="^insert\\s";
//
//    /**查找SQL类型的正则表达式： UPDATE*/
//    private static final String SQL_TYPE_PATTERN_UPDATE="^update\\s";
//
//    /**查询SQL语句片段的正则表达式：gmt_modified片段 */
//    private static final String SQL_STATEMENT_PATTERN_MODIFIED = ",\\s*" + FIELD_MODIFIED + "\\s*=";
//
//    /**查询SQL语句片段的正则表达式：gmt_create片段 */
//    private static final String SQL_STATEMENT_PATTERN_CREATE=",\\s*"+FIELD_CREATE+"\\s*[,)]?";
//
//    /**查询SQL语句片段的正则表达式：where字句*/
//    private static final String SQL_STATEMENT_PATTERN_WHERE = "\\s+where\\s+";
//
//    /**查询SQL语句片段的正则表达式：values子句*/
//    private static final String SQL_STATEMENT_PATTERN_VALUES="\\)\\s*values?\\s*\\(";
//
//    public Object intercept(Invocation invocation) throws Throwable {
//        //日志
//        log.debug("准备拦截SQL语句。。。。");
//        //获取boundSql，即：封装了即将执行的SQL语句及相关数据的对象
//        BoundSql boundSql=getBoundSql(invocation);
//
//        // 从boundSql中获取SQL语句
//        String sql=getSql(boundSql);
//
//        // 日志
//        log.debug("原SQL语句：{}", sql);
//
//        // 准备新SQL语句
//        String newSql=null;
//        //判断原SQL语句类型
//        switch(getOriginalSqlType(sql)){
//            case SQL_TYPE_INSERT:
//                log.debug("原sql语句是【insert】语句,准备补充更新时间....");
//                newSql=appendCreateTimeField(sql, LocalDateTime.now());
//                break;
//            case SQL_TYPE_UPDATE:
//                // 日志
//                log.debug("原SQL语句是【UPDATE】语句，准备补充更新时间……");
//                newSql = appendModifiedTimeField(sql, LocalDateTime.now());
//                break;
//        }
//        //应用新sql
//        if(newSql!=null){
//            //日志
//            log.debug("新的SQL语句是: {}", newSql);
//            reflectAttributeValue(boundSql,"sql", newSql);
//        }
//        return null;
//    }
//
//
//    /**
//     * <p>获取BoundSql对象，此部分代码相对固定</p>
//     * <p>注意：根据拦截类型不同，获取BoundSql的步骤并不相同，此处并未穷举所有方式！</p>
//     * @param invocation 调用对象
//     * @return 绑定SQL的对象
//     */
//    private BoundSql getBoundSql(Invocation invocation) {
//        Object invocationTarget=invocation.getTarget();
//        if(invocationTarget instanceof  StatementHandler){
//            StatementHandler statementHandler=(StatementHandler) invocationTarget;
//            System.out.println(statementHandler.getBoundSql().getSql());
//            log.debug("statementHandler.getBoundSql().getSql()::"+statementHandler.getBoundSql().getSql());
//            return  statementHandler.getBoundSql();
//        }else{
//            throw  new RuntimeException("获取StatementHandler失败！请检查拦截器配置！");
//        }
//    }
//
//
//    /**
//     * 从BoundSql对象中获取SQL语句
//     * @param boundSql BoundSql对象
//     * @return 将BoundSql对象中封装的SQL语句进行转换小写、去除多余空白后的SQL语句
//     */
//    private String getSql(BoundSql boundSql) {
//        return boundSql.getSql().toLowerCase().replaceAll("\\s+", " ").trim();
//    }
//
//    /**
//     * 获取原SQL语句类型
//     * @param sql 原SQL语句
//     * @return SQL语句类型
//     */
//    private int getOriginalSqlType(String sql) {
//        Pattern pattern=Pattern.compile(SQL_TYPE_PATTERN_INSERT, Pattern.CASE_INSENSITIVE);
//        if(pattern.matcher(sql).find()){
//            return SQL_TYPE_INSERT;
//        }
//        pattern=Pattern.compile(SQL_TYPE_PATTERN_UPDATE, Pattern.CASE_INSENSITIVE);
//        if(pattern.matcher(sql).find()){
//            return SQL_TYPE_UPDATE;
//        }
//        return SQL_TYPE_OTHER;
//    }
//
//
//
//    /*    public static void main(String[] args) {
//        //new InsertUpdateTimeInterceptor().appendCreateTimeField("insert into ams_admin_role (admin_id,role_id)values(1,1)",LocalDateTime.now());
//        new InsertUpdateTimeInterceptor().appendModifiedTimeField("update ams_admin_role set admin_id=2,role_id=1 where id=3",LocalDateTime.now());
//    }
//    */
//
//    private String appendCreateTimeField(String sqlCode, LocalDateTime dateTime) {
//        // 如果 SQL 中已经包含 gmt_create 就不在添加这两个字段了
//
//        //Pattern是包含两个字段名的一段sql片段
//        Pattern gmtPattern=Pattern.compile(SQL_STATEMENT_PATTERN_CREATE,Pattern.CASE_INSENSITIVE);
//        if (gmtPattern.matcher(sqlCode).find()){
//            log.debug("已经包含 gm_create 不再添加 时间字段");
//            return null;
//        }
//
//        // INSERT into table (xx, xx, xx ) values (?,?,?)中 查找 ) values ( 的位置
//        StringBuilder sql=new StringBuilder(sqlCode);
//
//        //此Pattern是包含  ")values("  的正则对象
//        Pattern valuesClausePattern=Pattern.compile(SQL_STATEMENT_PATTERN_VALUES,Pattern.CASE_INSENSITIVE);
//        Matcher valuesClauseMatcher=valuesClausePattern.matcher(sql);
//        if(valuesClauseMatcher.find()) {
//            int start = valuesClauseMatcher.start();
//            int end = valuesClauseMatcher.end();
//            String str = valuesClauseMatcher.group();
//
//            //举例如下：
//            //"insert into ams_admin_role (admin_id,role_id)values(1,1)"
//            //找到字符串：)values(的位置是：44,52
//            //提示： 从0开始数 )values( 左括号的位置是44    第一个1的位置是52
//
//            log.debug("InsertUpdateTimeInterceptor::appendCreateTimeField():::找到字符串：{}的位置是：{},{}", str, start, end);
//            // 插入字段列表
//            String fieldNames = "," + FIELD_CREATE + "," + FIELD_MODIFIED;
//            sql.insert(start, fieldNames);//从")values("的开始出插入 "gmt_create"和"gmt_modified"两个字段名
//
//            //"insert into ams_admin_role (admin_id,role_id)values(1,1)",
//            //44位置处插入字段列表,gmt_create,gmt_modified
//            log.debug("InsertUpdateTimeInterceptor::appendCreateTimeField()::: {}位置处插入字段列表{}", start,fieldNames);
//            // 定义查找参数值位置的 正则表达 “)”
//            Pattern paramPositionPattern = Pattern.compile("\\)");
//            Matcher paramPositionMatcher = paramPositionPattern.matcher(sql);
//            // 从 ) values ( 的后面位置 end 开始查找 结束括号的位置
//            String param = ", '" + dateTime + "','" + dateTime + "'";//拼接出两个时间数据的sql片段
//            int position = end + fieldNames.length();//从sql中匹配到  ")values(" 的位置加上  ",gmt_create,gmt_update"的长度
//
//            //end 52 + fieldNames.length()  24=76
//            log.debug("InsertUpdateTimeInterceptor::appendCreateTimeField()::: end{} + fieldNames.length(){}={}", end,fieldNames.length(),position);
//            while (paramPositionMatcher.find(position)) {
//                start = paramPositionMatcher.start();
//                end = paramPositionMatcher.end();
//                str = paramPositionMatcher.group();
//
//                //insert into ams_admin_role (admin_id,role_id,gmt_create,gmt_modified)values(1,1)
//                //找到参数值插入位置),79,80 //从最后一个 ) 符号位置处(下标位置为79的位置)开始插入
//                log.debug("sql '{}' 找到参数值插入位置{},{},{}", sql,str, start, end);
//                sql.insert(start, param);//把两个时间数值从start位置开始插入到sql语句中
//
//                //在79处插入参数值, '2022-12-25T21:38:42.410','2022-12-25T21:38:42.410'
//                log.debug("在{}处插入参数值{}", start, param);
//                position = end + param.length();
//            }
//            if (position == end) {
//                log.warn("没有找到插入数据的位置");
//                return null;
//            }
//
//
//        }else{
//            log.warn("没有找到  ')values(' ");
//            return null;
//        }
//        //insert into ams_admin_role (admin_id,role_id,gmt_create,gmt_modified)values(1,1, '2022-12-25T22:27:39.070','2022-12-25T22:27:39.070')
//        log.debug("生成SQL：{}", sql);
//        return  sql.toString();
//    }
//
//
//
//    //测试结果如下：
//    //"update ams_admin_role set admin_id=2,role_id=1 where id=3"
//    // DEBUG com.zyq.interceptor.InsertUpdateTimeInterceptor - 在原SQL语句的 46位置 到 53位置 找到  where
//    // DEBUG com.zyq.interceptor.InsertUpdateTimeInterceptor - 在原SQL语句: 46中 插入sql片段 ,gmt_modified='2022-12-26T01:10:13.854'
//    // DEBUG com.zyq.interceptor.InsertUpdateTimeInterceptor - 最终生成的SQL语句为:
//    // update ams_admin_role set admin_id=2,role_id=1,gmt_modified='2022-12-26T01:10:13.854' where id=3
//    private String appendModifiedTimeField(String sqlStatement, LocalDateTime dateTime) {
//        //此Pattern包含gmt_modified字段名的正则
//        Pattern gmtPattern = Pattern.compile(SQL_STATEMENT_PATTERN_MODIFIED, Pattern.CASE_INSENSITIVE);
//        //如果sqlStatement的sql语句中包含gmt_modified字段名。就不再执行本方法中拼接gmt_modified字段信息的代码
//        if (gmtPattern.matcher(sqlStatement).find()) {
//            log.debug("原SQL语句中已经包含gmt_modified，将不补充添加时间字段");
//            return null;
//        }
//        StringBuilder sql = new StringBuilder(sqlStatement);
//        //此Pattern正则中包含了where关键字
//        Pattern whereClausePattern = Pattern.compile(SQL_STATEMENT_PATTERN_WHERE, Pattern.CASE_INSENSITIVE);
//        //Matcher匹配器表示用于将上边的正则和sql进行匹配
//        Matcher whereClauseMatcher = whereClausePattern.matcher(sql);
//        //查找where字句的位置
//        if(whereClauseMatcher.find()){
//            int start=whereClauseMatcher.start();
//            int end=whereClauseMatcher.end();
//            String clause= whereClauseMatcher.group();
//            log.debug("在原SQL语句的 {}位置 到 {}位置 找到 {}", start, end, clause);
//            String newSetClause=","+FIELD_MODIFIED +"='" +dateTime+"'";
//            sql.insert(start, newSetClause);
//            log.debug("在原SQL语句: {}中 插入sql片段 {}", start, newSetClause);
//            log.debug("最终生成的SQL语句为: {}", sql);
//            return sql.toString();
//        }
//        return null;
//    }
//
//
//    /**
//     * 包装目标对象:包装,为目标对象创建一个代理对象
//     * @param target
//     * @return
//     */
//    public Object plugin(Object target){
//        //本方法的代码是相对固定的
//        if(target instanceof  StatementHandler){
//            // 我们可以借助Plugin的wrap方法来使用Interceptor包装我们目标对象
//            Object wrap = Plugin.wrap(target, this);
//            // 返回为当前target创建的动态代理对象
//            return wrap;
//        }else {
//            return target;
//        }
//    }
//
//    //setProperties方法：
//    //在全局配置文件注册插件时，可以设置一些property属性，通过该方法的入参获取。
//    //如以下的全局配置文件，设置了两个property，可以通过入参获取到：
//    //    <!-- plugins:注册插件 -->
//    //    <plugins>
//    //        <plugin interceptor="com.shen.mybaties.dao.MyFirstPlugin">
//    //            <property name="username" value="root" />
//    //            <property name="password" value="123456" />
//    //        </plugin>
//    //    </plugins>
//
//    //将插件注册时的property属性设置进来
//    public void setProperties(Properties properties) {
//        // 无须执行操作
//        System.out.println("插件配置的信息:" + properties);
//    }
//
//    /**
//     * <p>通过反射，设置某个对象的某个属性的值</p>
//     *
//     * @param boundSql         需要设置值的对象
//     * @param attributeName  需要设置值的属性名称
//     * @param newSql 新的值
//     * @throws NoSuchFieldException   无此字段异常
//     * @throws IllegalAccessException 非法访问异常
//     */
//    private void reflectAttributeValue(BoundSql boundSql, String attributeName, String newSql) throws NoSuchFieldException, IllegalAccessException {
//        Field field=boundSql.getClass().getDeclaredField(attributeName);
//        log.debug("InsertUpdateTimeInterceptro::reflectAttributeValue()::boundSql::"+boundSql);
//        field.setAccessible(true);
//        field.set(boundSql,newSql);
//    }
//
//}
//




















